package cn.touna.jss.modules.third.bairong.util;

import cn.touna.risk.api.enums.SystemErrorCodeEnum;
import cn.touna.risk.api.utils.JSONUtil;
import cn.touna.jss.common.enums.BaiRongResultEnum;
import cn.touna.jss.common.exception.ResponseException;
import cn.touna.jss.common.factory.ResponseFactory;
import cn.touna.jss.common.properties.disconf.BairongProperties;
import cn.touna.jss.common.util.JssConstant;
import cn.touna.jss.common.util.MD5Util;
import cn.touna.jss.modules.third.bairong.entity.BaiRongEntity;
import cn.touna.risk.api.domain.Response;
import cn.touna.risk.api.exception.ServiceException;
import cn.touna.risk.api.http.HttpsUtil;
import cn.touna.risk.cache.redis.RedisCache;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.bfd.facade.MerchantServer;
import com.touna.loan.log.service.TracerContextUtil;
import org.apache.commons.lang3.StringUtils;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;


/**
 * 百融
 * <p>
 */

@Service
public class BairongServiceHandler {

    private static final Logger logger = LogManager.getLogger(BairongServiceHandler.class);

    @Autowired
    private BairongProperties bairongConfig;

    @Autowired
    private RedisCache redisCache;


    /**
     * 查询百融数据
     *
     * @param method
     * @param baiRongEntity
     * @return
     * @throws Exception
     */
    public String querySingleData(String method, BaiRongEntity baiRongEntity) throws Exception {
        MerchantServer merchantServer = new MerchantServer();
        String token = getToken(merchantServer);
        String result = getApiSingleData(token, method, baiRongEntity, merchantServer);
        return result;
    }

    /**
     * 非SDK方式请求
     *
     * @param method
     * @param apiUrl
     * @param baiRongEntity
     * @return
     * @throws Exception
     */
    public String queryHttpsData(String method, String apiUrl, BaiRongEntity baiRongEntity) throws Exception {
        String token = getToken();
        String result = getHttpBatchData(token, method, apiUrl, baiRongEntity);
        return result;
    }

    /**
     * 查询多个联系人的百融数据
     * @param meal 套餐
     * @param baiRongEntity
     * @return
     * @throws Exception
     */
    public Response queryBatchData(String meal, BaiRongEntity baiRongEntity){
        try{
            MerchantServer merchantServer = new MerchantServer();
            String token = getToken(merchantServer);
            JSONObject result = getApiBatchData(token, meal, baiRongEntity, merchantServer);
            return ResponseFactory.success(result);
        }catch (ResponseException e){
            logger.error(e.getMessage(),e);
            return e.getResponse();
        }catch (Exception e){
            logger.error(e.getMessage(),e);
            return ResponseFactory.fail(SystemErrorCodeEnum.JSS_CALL_EXTSYSTEM_ERROR, e.getMessage());
        }
    }

    /**
     * 获取token
     * @param merchantServer
     * @return
     */
    private String getToken(MerchantServer merchantServer) throws ResponseException {
        String cahceToken = redisCache.get(JssConstant.TOKEN_BAIRONG_KEY);
        if (StringUtils.isNotBlank(cahceToken)) {
            return cahceToken;
        }
        return resetToken(merchantServer);
    }

    private String getToken() throws Exception {
        //登陆
        String cahceToken = redisCache.get(JssConstant.TOKEN_BAIRONG_KEY);
        logger.info("Bairong cacheToken:{}", cahceToken);
        if (StringUtils.isNotBlank(cahceToken)) {
            return cahceToken;
        }
        String token = resetToken();
        if (StringUtils.isBlank(token)) {
            throw new ServiceException("登录百融服务失败");
        }
        return token;
    }

    /**
     * 重置token
     *
     * @param merchantServer
     * @return
     * @throws Exception
     */
    private String resetToken(MerchantServer merchantServer) throws ResponseException {
        String result = null;
        try {
            result = merchantServer.login(bairongConfig.getUsername(), bairongConfig.getPassword(), "LoginApi", bairongConfig.getApiCode());
        } catch (Exception e) {
            Response response = ResponseFactory.fail(SystemErrorCodeEnum.JSS_CALL_EXTSYSTEM_ERROR,e.getMessage());
            throw new ResponseException(response);
        }
        JSONObject resObj = JSONObject.parseObject(result);
        String code = resObj.getString("code");
        if ("00".equals(code)) {
            String tokenId =  resObj.getString("tokenid");
            redisCache.set(JssConstant.TOKEN_BAIRONG_KEY, tokenId,1, TimeUnit.HOURS);
            return tokenId;
        }
        Response response = ResponseFactory.fail(SystemErrorCodeEnum.JSS_EXTSYSTEM_RESP_ERROR,"登录失败");
        throw new ResponseException(response);
    }

    /**
     * 非SDK方式
     *
     * @return
     * @throws Exception
     */
    private String resetToken() throws Exception {
        String login_result = resetHttpToken();
        logger.info("Bairong getToken ,username:{},apiCode:{},result:{}", bairongConfig.getUsername(), bairongConfig.getApiCode(), login_result);
        String code = JSONUtil.getString(login_result, "code", null);
        if ("00".equals(code)) {
            String tokenId = JSONUtil.getString(login_result, "tokenid", null);
            redisCache.set(JssConstant.TOKEN_BAIRONG_KEY, tokenId);
            return tokenId;
        }
        return null;
    }

    private String resetHttpToken() throws Exception {
        Map<String, String> headParams = new HashMap<>();
        headParams.put("Content-Type", "application/x-www-form-urlencoded");
        Map<String, String> bodyMap = new HashMap<>();
        bodyMap.put("userName", bairongConfig.getUsername());
        bodyMap.put("password", bairongConfig.getPassword());
        bodyMap.put("apiCode", bairongConfig.getApiCode());
        String result = HttpsUtil.getInstance().post(bairongConfig.getLoginUrl(), headParams, bodyMap);
        return result;
    }

    /**
     * 百融API调用数据
     * @param token
     * @param meal
     * @param baiRongEntity
     * @param merchantServer
     * @return
     * @throws Exception
     */
    private JSONObject getApiBatchData(String token, String meal, BaiRongEntity baiRongEntity, MerchantServer merchantServer) throws ResponseException{
        JSONObject jsonData = new JSONObject();
        jsonData.put("apiName", bairongConfig.getApiNameBatch());
        jsonData.put("tokenid", token);
        JSONObject reqData = new JSONObject();
        reqData.put("meal", meal);  //单独调用，注释为默认打包调用全部开通模块。
        reqData.put("id", baiRongEntity.getIdCard());  //身份证号
        reqData.put("name", baiRongEntity.getName());  //姓名
        if (StringUtils.isNotBlank(baiRongEntity.getFriendMobilePhone())) {
            reqData.put("linkman_cell", baiRongEntity.getFriendMobilePhone());  //联系人的手机号
        }
        JSONArray cells = new JSONArray();
        cells.add(baiRongEntity.getMobile());
        reqData.put("cell", baiRongEntity.getMobile());
        jsonData.put("reqData", reqData);
        logger.info("Bairong,url:{},apiCode:{},params{}", meal, bairongConfig.getApiCode(), jsonData.toJSONString());

        String result = null;
        try {
            result = merchantServer.getApiData(jsonData.toJSONString(), bairongConfig.getApiCode());
            logger.info(TracerContextUtil.getTraceId() + " result: " +  result);
        } catch (Exception e) {
            logger.error(e.getMessage(),e);
            Response response = ResponseFactory.fail(SystemErrorCodeEnum.JSS_CALL_EXTSYSTEM_ERROR,e.getMessage());
            throw new ResponseException(response);
        }
        JSONObject resObj = JSONObject.parseObject(result);
        String code = resObj.getString("code");
        if ("100007".equals(code)) {
            String resetToken = resetToken(merchantServer);
            jsonData.put("tokenid", resetToken);
            try {
                result = merchantServer.getApiData(jsonData.toJSONString(), bairongConfig.getApiCode());
                logger.info(TracerContextUtil.getTraceId() + " result: " +  result);
                resObj = JSONObject.parseObject(result);
                code = resObj.getString("code");
                if(!"00".equals(code)){
                    String msg = BaiRongResultEnum.getValue(code);
                    throw new ResponseException(ResponseFactory.fail(SystemErrorCodeEnum.JSS_EXTSYSTEM_RESP_ERROR,code + ":" + msg));
                }
            } catch (Exception e) {
                logger.error(e.getMessage(),e);
                Response response = ResponseFactory.fail(SystemErrorCodeEnum.JSS_CALL_EXTSYSTEM_ERROR,e.getMessage());
                throw new ResponseException(response);
            }
        }
        return resObj;
    }

    /**
     * 非SDK方式调用
     *
     * @param token
     * @param meal
     * @param apiUrl
     * @param baiRongEntity
     * @return
     * @throws Exception
     */
    private String getHttpBatchData(String token, String meal, String apiUrl, BaiRongEntity baiRongEntity) throws Exception {
        JSONObject reqData = new JSONObject();
        reqData.put("meal", meal);
        reqData.put("id", baiRongEntity.getIdCard());  //身份证号
        reqData.put("name", baiRongEntity.getName());  //姓名
        if (StringUtils.isNotBlank(baiRongEntity.getFriendMobilePhone())) {
            reqData.put("linkman_cell", baiRongEntity.getFriendMobilePhone());  //联系人的手机号
        }
        reqData.put("cell", baiRongEntity.getMobile());
        Map<String, String> headParams = new HashMap<>();
        headParams.put("Content-Type", "application/x-www-form-urlencoded");
        Map<String, String> bodyparams = new HashMap<>();
        bodyparams.put("tokenid", token);
        bodyparams.put("apiCode", bairongConfig.getApiCode());
        String reqDataStr = reqData.toString(); //确保checkCode正确
        bodyparams.put("jsonData", reqDataStr);
        String prifexCode = MD5Util.getSign(bairongConfig.getApiCode(), token);
        bodyparams.put("checkCode", MD5Util.getSign(reqDataStr, prifexCode));
        logger.info("Bairong,url:{},apiCode:{},params:{}", apiUrl, bairongConfig.getApiCode(), bodyparams.toString());
        String result = HttpsUtil.getInstance().post(apiUrl, headParams, bodyparams);
        String code = JSONUtil.getString(result, "code", null);
        if (code != null && "100007".equals(code)) {
            String resetToken = resetToken();
            bodyparams.put("tokenid", resetToken);
            result = HttpsUtil.getInstance().post(apiUrl, headParams, bodyparams);
            ;
        }
        return result;
    }

    /**
     * 百融 单独调用Api数据
     * @param token
     * @param meal
     * @param
     * @return
     */
    private String getApiSingleData(String token, String meal, BaiRongEntity baiRongEntity, MerchantServer merchantServer) throws Exception{
        JSONObject jsonData = new JSONObject();
        jsonData.put("apiName", bairongConfig.getApiNameSingle());
        jsonData.put("tokenid", token);
        JSONObject reqData = new JSONObject();
        reqData.put("meal", meal);  //单独调用，注释为默认打包调用全部开通模块。
        reqData.put("id", baiRongEntity.getIdCard());  //身份证号
        reqData.put("name", baiRongEntity.getName());  //姓名
        reqData.put("cell", baiRongEntity.getMobile());  //用户手机号
        jsonData.put("reqData", reqData);
        logger.info("Bairong,url:{},apiCode:{},params{}", meal, bairongConfig.getApiCode(), jsonData.toJSONString());
        String result = merchantServer.getApiData(jsonData.toJSONString(), bairongConfig.getApiCode());
        String code = JSONUtil.getString(result, "code", null);
        if (code != null && "100007".equals(code)) {
            String resetToken = resetToken(merchantServer);
            jsonData.put("tokenid", resetToken);
            result = merchantServer.getApiData(jsonData.toJSONString(), bairongConfig.getApiCode());
        }
        return result;
    }

}
